/*
 * Microsecond timer functions for Flying Fox
 *
 * by Zik Saleeba 2008-03-07
 */

#ifndef TIMER_H
#define TIMER_H

/* type definitions */
struct RawTime
{
    unsigned long MSBTime;      /* in 8ms increments */
    unsigned long LSBTime;      /* in 1/6 microsecond increments */
};

/* functions */
void Timer_Init(void);
void Timer_Reset(void);
unsigned long long Timer_GetMicroSeconds(void);
unsigned long long Timer_CookTime(struct RawTime Time);

/* internal module variables */
extern unsigned long Timer_CurrentTime8ms;  /* the number of 8ms intervals since we started */

/* fast inline functions */
static struct RawTime Timer_GetRawTime(void)
{
    struct RawTime Time;
    unsigned long MSBTime2;
    
    /* try to get the time once */
    Time.MSBTime = Timer_CurrentTime8ms;
    Time.LSBTime = AT91C_BASE_TC0->TC_CV;
    
    /* did the timer overflow while we were doing that? */
    MSBTime2 = Timer_CurrentTime8ms;
    if (MSBTime2 != Time.MSBTime)
    {
        /* do it again - we're so close to the previous overflow
         * that another overflow won't happen this time */
        Time.LSBTime = AT91C_BASE_TC0->TC_CV;
        Time.MSBTime = MSBTime2;
    }
    
    return Time;
}

#endif /* TIMER_H */
